package com.jeomo.mem.starter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jeomo.base.starter.service.impl.BaseServiceImpl;
import com.jeomo.common.core.util.StringUtils;
import com.jeomo.masterdata.starter.entity.Goods;
import com.jeomo.masterdata.starter.mapper.GoodsMapper;
import com.jeomo.masterdata.starter.service.ILevelService;
import com.jeomo.mem.starter.dto.MemberDiscountRuleDto;
import com.jeomo.mem.starter.entity.MemberDiscountRule;
import com.jeomo.mem.starter.entity.MemberDiscountRuleExe;
import com.jeomo.mem.starter.entity.MemberDiscountRuleList;
import com.jeomo.mem.starter.mapper.MemberDiscountRuleExeMapper;
import com.jeomo.mem.starter.mapper.MemberDiscountRuleListMapper;
import com.jeomo.mem.starter.mapper.MemberDiscountRuleMapper;
import com.jeomo.mem.starter.service.IMemberDiscountService;
import com.jeomo.mem.starter.util.MemberUtil;
import com.jeomo.shiro.util.OrgUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 会员折扣服务实现
 * @author:Jackpot
 * @create 2020-09-24 16:43
 * @description:
 */
@Service
@Transactional
public class MemberDiscountServiceImpl extends BaseServiceImpl<MemberDiscountRuleListMapper,MemberDiscountRuleList>
        implements IMemberDiscountService {

    private Logger logger = LoggerFactory.getLogger(MemberDiscountServiceImpl.class);

    private final String RULE_CODE = "rule_code";

    @Resource
    private MemberDiscountRuleMapper memberDiscountRuleMapper;
    @Resource
    private MemberDiscountRuleListMapper memberDiscountRuleListMapper;
    @Resource
    private MemberDiscountRuleExeMapper memberDiscountRuleExeMapper;
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private ILevelService levelService;

    @Override
    public  int saveRule(MemberDiscountRule memberRule, List<MemberDiscountRuleList> memberRuleList) {

        int result = 0;
        String code = memberRule.getCode();
        if (code!=null){
            MemberDiscountRule memberRule1 = memberDiscountRuleMapper.selectById(code);
            if (memberRule1 !=null){//修改规则
                result = saveRule(memberRule,memberRuleList,false);
            }else {//数据已被删除
                return -2;
            }
        }else{
            //新增规则
            result = saveRule(memberRule,memberRuleList,true);
        }
        return result;
    }

    @Override
    public int saveRule(MemberDiscountRule memberRule, List<MemberDiscountRuleList> memberRuleList, boolean addOrUpdate) {

        memberRule.setUseLevels(StringUtils.arrayToStr(memberRule.getLevelCodes()));
        String ruleIdIfConflict = verifyBeforeSave(memberRule, memberRuleList);
        if(ruleIdIfConflict!=null){
            return -3;
        }
        int masterResult = 0;
        String code = memberRule.getCode();
        if(addOrUpdate==true){
            //新增规则
            memberRule.setOrg(OrgUtil.getCurrOrg());
            masterResult = memberDiscountRuleMapper.insert(memberRule);
            code = memberRule.getCode();
        }else{
            //修改规则: 修改主表,删除子表原数据,新增子表数据
            masterResult = memberDiscountRuleMapper.updateById(memberRule);
            if(masterResult < 1) return -1;
            int delList = deleteRuleDetail(code);
        }
        int detailResult = insertRuleDetail(memberRule,memberRuleList);
        boolean b = saveRuleExec(memberRule, memberRuleList, addOrUpdate);
        return masterResult+detailResult;
    }

    @Override
    public int insertRuleDetail(MemberDiscountRule memberRule,List<MemberDiscountRuleList> memberDiscountRuleList) {
        String ruleCode = memberRule.getCode();
        Integer useRange = memberRule.getUseRange();
        Iterator<MemberDiscountRuleList> iterator = memberDiscountRuleList.iterator();
        while (iterator.hasNext()){
            MemberDiscountRuleList detail = iterator.next();
            detail.setRuleCode(ruleCode);
            detail.setBsType(useRange);
        }
        return saveBatch(memberDiscountRuleList) == true?1:0;
    }

    @Override
    public int deleteRule(String ruleCode) {
        int delMaster = memberDiscountRuleMapper.deleteById(ruleCode);
        int delList = deleteRuleDetail(ruleCode);
        int delList2 = deleteRuleExe(ruleCode);
        return delList+delMaster+delList2;
    }

    @Override
    public int deleteRuleExe(String ruleCode) {
        QueryWrapper<MemberDiscountRuleExe> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(RULE_CODE,ruleCode);
        return memberDiscountRuleExeMapper.delete(queryWrapper);
    }

    @Override
    public int deleteRuleDetail(String ruleCode) {
        QueryWrapper<MemberDiscountRuleList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(RULE_CODE,ruleCode);
        return memberDiscountRuleListMapper.delete(queryWrapper);
    }

    @Override
    public MemberDiscountRuleDto getMemberRuleById(String ruleCode) {
        MemberDiscountRule memberDiscountRule = memberDiscountRuleMapper.selectById(ruleCode);
        Map<String, String> levelMap = levelService.queryCache();
        MemberUtil.assignName(memberDiscountRule,levelMap);

        QueryWrapper<MemberDiscountRuleList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(RULE_CODE,ruleCode);
        List<MemberDiscountRuleList> memberDiscountRuleList = memberDiscountRuleListMapper.selectList(queryWrapper);
        MemberDiscountRuleDto memberDiscountRuleDto = new MemberDiscountRuleDto();
        memberDiscountRuleDto.setMemberDiscountRule(memberDiscountRule);
        memberDiscountRuleDto.setMemberDiscountRuleList(memberDiscountRuleList);
        return memberDiscountRuleDto;
    }

    @Override
    public List<MemberDiscountRule> getAllRules() {
        return memberDiscountRuleMapper.selectList(null);
    }


    /**
     * 保存前校验: 是否存在配置冲突的数据存在;<br/>
     * 配置积分规则: 等级+业务编码 确定唯一数据
     * @param memberRule
     * @param memberRuleList
     * @return 返回配置冲突的ruleId; 如果返回null 表示不冲突,校验通过;
     */
    private String verifyBeforeSave(MemberDiscountRule memberRule, List<MemberDiscountRuleList> memberRuleList){

        String[] levels =  memberRule.getLevelCodes();
        String useLevels=StringUtils.arrayToStr(levels);
        List<MemberDiscountRuleExe> memberDiscountRuleExes = memberDiscountRuleExeMapper.getDiscountRuleExesByLevels(useLevels);
        HashMap<String, String> curRuleMap = new HashMap<>(64);
        for (MemberDiscountRuleExe exe :memberDiscountRuleExes){
            String levelCode = exe.getLevelCode();
            String bsCode = exe.getBsCode();
            String ruleCode = exe.getRuleCode();
            curRuleMap.put(levelCode+bsCode,ruleCode);
        }

        String code = memberRule.getCode();
        for(String levelCode:levels){
            for(MemberDiscountRuleList bo :memberRuleList){
                String discountCode = curRuleMap.get(levelCode + bo.getCode());
                if(discountCode !=null && !discountCode.equals(code)){
                    return discountCode;
                }
            }
        }
        return null;
    }


    /**
     * 保存到规则执行单
     * @param memberDiscountRule
     * @param memberDiscountRuleList
     * @param addOrUpdate
     * @return
     */
    public boolean saveRuleExec(MemberDiscountRule memberDiscountRule, List<MemberDiscountRuleList> memberDiscountRuleList,boolean addOrUpdate) {

        String code = memberDiscountRule.getCode();
        //如果是修改,先删除该规则所有的执行数据
        if(addOrUpdate==false){
            QueryWrapper<MemberDiscountRuleExe> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(RULE_CODE,code);
            memberDiscountRuleExeMapper.delete(queryWrapper);
        }
        //准备执行单数据
        List<MemberDiscountRuleExe> memberDiscountRuleExes = new ArrayList<>();
        double discount = memberDiscountRule.getDiscount();
        String[] levels = memberDiscountRule.getLevelCodes();
        //如果该积分规则的会员等级配置3个,使用范围明细是100个,则把数据平铺开来, 3*100=300条数据存储到执行单上
        for(String level:levels){
            for(MemberDiscountRuleList bo :memberDiscountRuleList){
                String bsCode = bo.getCode();

                MemberDiscountRuleExe memberDiscountRuleExe = new MemberDiscountRuleExe();
                memberDiscountRuleExe.setRuleCode(code);
                memberDiscountRuleExe.setLevelCode(level);
                memberDiscountRuleExe.setBsCode(bsCode);
                memberDiscountRuleExe.setDiscount(discount);
                memberDiscountRuleExes.add(memberDiscountRuleExe);
            }
        }
        //新增
        int insert =0;
        int size = memberDiscountRuleExes.size();
        for(MemberDiscountRuleExe exe :memberDiscountRuleExes){
            insert += memberDiscountRuleExeMapper.insert(exe);
        }
        return insert==size;
    }

    @Override
    public Double getDiscount(String levelCode, String goodsCode) {

        List<MemberDiscountRuleExe> memberDiscountRuleExes = memberDiscountRuleExeMapper.getDiscountRuleExesByLevel(levelCode);
        HashMap<String, Double> curRuleMap = new HashMap<>(64);
        for (MemberDiscountRuleExe exe :memberDiscountRuleExes){
            String bsCode = exe.getBsCode();
            Double discount = exe.getDiscount();
            curRuleMap.put(bsCode,discount);
        }
        Double discount = null;
        //商品对应的规则
        discount = curRuleMap.get(goodsCode);
        if (discount!=null) return discount;
        Goods goods = goodsMapper.selectById(goodsCode);
        if (goods == null) return null;
        //查询商户的规则
        String merchantCode = goods.getMerchantCode();
        discount = curRuleMap.get(merchantCode);
        return discount;
    }
}
